#include "declare.hpp"

// 检查用户输入的 linkID 是否为正整数
bool MapSystem::_CheckLinkID(int &linkID)
{
    return linkID > 0;
}

// 获取用户输入的操作选项，确保输入的操作是有效的（0 或 1）
int MapSystem::_GetOption()
{
    int option;
    std::cin >> option;
    // 当输入不是 0 或 1 时，提示重新输入
    while (option != 0 && option != 1)
    {
        std::cout << "输入无效,请按1重新输入,按0退出@> ";
        std::cin >> option;
    }
    return option;
}

// 在数组中查找指定 linkID 的记录
std::vector<Node>::iterator MapSystem::_FindVectorRecord(INT32U linkID)
{
    return std::find_if(_vector_array.begin(), _vector_array.end(),
                        [&linkID](const Node &node)
                        { return node._ulLinkID == linkID; });
}

// 在链表中查找指定 linkID 的记录
std::list<Node>::iterator MapSystem::_FindListRecord(INT32U linkID)
{
    return std::find_if(_nodeList.begin(), _nodeList.end(),
                        [&linkID](const Node &node)
                        { return node._ulLinkID == linkID; });
}

// 添加记录函数
void MapSystem::_AddRecord()
{
    int inputLinkID;      // 用于存储用户输入的 linkID
    INT32U linkID;        // 转换后的无符号 linkID
    std::string roadName; // 道路名称
    bool flag = true;

    while (flag)
    {
        // 获取用户输入的 linkID 和道路名称
        std::cout << "请输入要插入记录的linkID(50000以上正整数) 和 roadName@> ";
        std::cin >> inputLinkID >> roadName;

        // 检查 linkID 的合法性
        if (!_CheckLinkID(inputLinkID))
        {
            _log(ERROR, "输入的linkID不合法,请输入正整数");
            continue;
        }
        linkID = static_cast<INT32U>(inputLinkID);

        // 检查 linkID 是否已经存在于数组中，确保唯一性
        if (_FindVectorRecord(linkID) != _vector_array.end())
        {
            _log(WARNING, "已经有linkID = %u 的道路,需要保证linkID的唯一性", linkID);
            std::cout << "请重新选择,按1重新输入,按0退出@> ";
            if (_GetOption() == 0)
                return; // 如果用户选择退出则返回
        }
        else
        {
            flag = false; // 退出循环
        }
    }

    // 创建新节点，并随机生成某些字段的值
    Node newnode = {(INT16U)(roadName.size() + rand() % 3000),
                    linkID,
                    (INT16U)(rand() % 30000),
                    (INT32U)(rand() % 30000),
                    roadName};

    // 将新节点插入到数组和链表中
    _vector_array.push_back(newnode);
    _nodeList.push_back(newnode);

    // 打印添加成功的记录信息
    auto ret_vector_pos = _FindVectorRecord(linkID);
    if (ret_vector_pos != _vector_array.end())
    {
        _log(INFO, "添加成功,添加的记录为:\nRecord Size: %d, Link ID: %u, Name Size: %d, Start Node Info: %d, Road Name: %s",
             ret_vector_pos->_usRecSize, ret_vector_pos->_ulLinkID, ret_vector_pos->_usRoadNameSize, ret_vector_pos->_ulStaNodeInfo, ret_vector_pos->_pcRoadName.c_str());
    }
}

// 删除记录函数
void MapSystem::_DeleteRecord()
{
    int inputLinkID; // 用户输入的 linkID
    INT32U linkID;   // 转换后的无符号 linkID
    bool flag = true;

    while (flag)
    {
        std::cout << "请输入要删除记录的linkID@> ";
        std::cin >> inputLinkID;

        // 检查 linkID 的合法性
        if (!_CheckLinkID(inputLinkID))
        {
            _log(ERROR, "输入的linkID不合法,请输入正整数");
            continue;
        }
        linkID = static_cast<INT32U>(inputLinkID);

        // 查找要删除的记录
        auto ret_vector_pos = _FindVectorRecord(linkID);
        if (ret_vector_pos != _vector_array.end())
        {
            // 打印找到的记录并确认是否删除
            _log(INFO, "找到记录:\nRecord Size: %d, Link ID: %u, Name Size: %d, Start Node Info: %d, Road Name: %s",
                 ret_vector_pos->_usRecSize, ret_vector_pos->_ulLinkID, ret_vector_pos->_usRoadNameSize, ret_vector_pos->_ulStaNodeInfo, ret_vector_pos->_pcRoadName.c_str());
            std::cout << "[Warning] 请确认是否删除? 1.确定,0.取消 Please Enter@> ";
            if (_GetOption() == 1)
            {
                // 从数组和链表中删除记录
                _vector_array.erase(ret_vector_pos);
                auto ret_list_pos = _FindListRecord(linkID);
                if (ret_list_pos != _nodeList.end())
                {
                    _nodeList.erase(ret_list_pos);
                }
                std::cout << "删除成功 " << std::endl;
            }
            else
            {
                _log(INFO, "已取消删除操作");
            }
            return; // 操作完成，退出函数
        }
        else
        {
            // 没有找到对应记录，提示用户重新输入
            _log(WARNING, "没有找到linkID = %u 的道路", linkID);
            std::cout << "请重新选择,按1重新输入,按0退出;@> ";
            if (_GetOption() == 0)
                flag = false; // 用户选择退出
        }
    }
}

// 修改记录函数
void MapSystem::_ModifyRecord()
{
    int inputLinkID; // 用户输入的 linkID
    INT32U linkID;   // 转换后的无符号 linkID
    bool flag = true;

    while (flag)
    {
        std::cout << "请输入要修改记录的linkID@> ";
        std::cin >> inputLinkID;

        // 检查 linkID 的合法性
        if (!_CheckLinkID(inputLinkID))
        {
            _log(ERROR, "输入的linkID不合法,请输入正整数");
            continue;
        }
        linkID = static_cast<INT32U>(inputLinkID);

        // 查找要修改的记录
        auto ret_vector_pos = _FindVectorRecord(linkID);
        if (ret_vector_pos != _vector_array.end())
        {
            // 打印找到的记录信息
            std::cout << "找到以下记录:\nRecord Size: " << ret_vector_pos->_usRecSize
                      << ", Link ID: " << ret_vector_pos->_ulLinkID
                      << ", Name Size: " << ret_vector_pos->_usRoadNameSize
                      << ", Start Node Info: " << ret_vector_pos->_ulStaNodeInfo
                      << ", Road Name: " << ret_vector_pos->_pcRoadName << std::endl;

            // 获取新的 linkID 和 roadName
            INT32U newlinkID;
            std::string newRoadName;
            std::cout << "请输入新的linkID(50000以上正整数) 和 roadName@> ";
            std::cin >> newlinkID >> newRoadName;

            // 确保新的 linkID 是唯一的
            if (_FindVectorRecord(newlinkID) != _vector_array.end())
            {
                _log(WARNING, "已经有linkID = %u 的道路,请保证linkID的唯一性", newlinkID);
                continue;
            }

            // 修改数组和链表中的记录
            ret_vector_pos->_ulLinkID = newlinkID;
            ret_vector_pos->_pcRoadName = newRoadName;

            auto ret_list_pos = _FindListRecord(linkID);
            if (ret_list_pos != _nodeList.end())
            {
                ret_list_pos->_ulLinkID = newlinkID;
                ret_list_pos->_pcRoadName = newRoadName;
            }

            // 打印修改后的记录信息
            _log(INFO, "修改成功,修改后的记录为:\nRecord Size: %d, Link ID: %u, Name Size: %d, Start Node Info: %d, Road Name: %s",
                 ret_vector_pos->_usRecSize, ret_vector_pos->_ulLinkID, ret_vector_pos->_usRoadNameSize, ret_vector_pos->_ulStaNodeInfo, ret_vector_pos->_pcRoadName.c_str());

            return; // 操作完成，退出函数
        }
        else
        {
            // 没有找到对应记录，提示用户重新输入
            _log(WARNING, "没有找到linkID = %u 的道路", linkID);
            std::cout << "请重新选择,按1重新输入,按0退出;@> ";
            if (_GetOption() == 0)
                flag = false; // 用户选择退出
        }
    }
}
